/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.security.services.impl;

import java.util.UUID;

import org.libermundi.theorcs.core.services.impl.AbstractManagerImpl;
import org.libermundi.theorcs.security.dao.UserDao;
import org.libermundi.theorcs.security.model.User;
import org.libermundi.theorcs.security.services.UserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Implementation of UserManager
 *
 */
@Service("userManager")
@Transactional(rollbackFor = Exception.class, propagation=Propagation.REQUIRED)
public class UserManagerImpl extends AbstractManagerImpl<User,Long> implements UserManager {
	private static final Logger logger = LoggerFactory.getLogger(UserManagerImpl.class);
	
	@Autowired
	public UserManagerImpl(UserDao userDao) {
		super();
		setDao(userDao);
	}
	
	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.main.services.UserManager#getUser()
	 */
	@Override
	public User getUser() {
		User user = new User();
		user.setUid(UUID.randomUUID().toString());
		user.setEnabled(Boolean.FALSE);
		user.setActive(Boolean.FALSE);
		user.setNickName("Temporary");
		user.setEmail("test@localhost.com");
		return user;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByUsername(java.lang.String)
	 */
	@Override
	public User getUserByUsername(String username) {
		return getUserByUsername(username,Boolean.FALSE);
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByUsername(java.lang.String, boolean)
	 */
	@Override
	public User getUserByUsername(String username, boolean force) {
		return ((UserDao) _dao).getUserByUsername(username,force);
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByNickname(java.lang.String)
	 */
	@Override
	public User getUserByNickname(String nickname) {
		return getUserByNickname(nickname,Boolean.FALSE);
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByNickname(java.lang.String, boolean)
	 */
	@Override
	public User getUserByNickname(String nickname, boolean force) {
		return ((UserDao) _dao).getUserByNickname(nickname,force);
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByUID(java.lang.String)
	 */
	@Override
	public User getUserByUID(String uid) {
		return getUserByUID(uid, Boolean.FALSE);
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByUID(java.lang.String, boolean)
	 */
	@Override
	public User getUserByUID(String uid, boolean force) {
		return ((UserDao)_dao).getUserByUID(uid,force);
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.impl.AbstractManagerImpl#initDao()
	 */
	@Override
	public void initialize() {
		if(getAllCount() == 0L) {
			if(logger.isDebugEnabled()) {
				logger.debug("Initializing User data");
			}
			User rootUser = getUser();
				rootUser.setUsername("root");
				rootUser.setPassword("root");
				rootUser.setNickName("Super Admin");
				rootUser.setFirstName("Super Administrator");
				rootUser.setLastName("");
				rootUser.setEmail("root@localhost");
				rootUser.setEnabled(Boolean.TRUE);
				rootUser.setDeleted(Boolean.FALSE);
				rootUser.setActive(Boolean.TRUE);
				rootUser.setAccountNonLocked(Boolean.TRUE);
				rootUser.setAccountNonExpired(Boolean.TRUE);
				rootUser.setCredentialsNonExpired(Boolean.TRUE);
			save(rootUser);				
			
			User adminUser = getUser();
				adminUser.setUsername("admin");
				adminUser.setPassword("admin");
				adminUser.setNickName("Admin");
				adminUser.setFirstName("Administrator");
				adminUser.setLastName("");
				adminUser.setEmail("admin@localhost");
				adminUser.setEnabled(Boolean.TRUE);
				adminUser.setDeleted(Boolean.FALSE);
				adminUser.setActive(Boolean.TRUE);
				adminUser.setAccountNonLocked(Boolean.TRUE);
				adminUser.setAccountNonExpired(Boolean.TRUE);
				adminUser.setCredentialsNonExpired(Boolean.TRUE);
			save(adminUser);
			
			User stdUser1 = getUser();
				stdUser1.setUsername("user1");
				stdUser1.setPassword("password");
				stdUser1.setNickName("User 1");
				stdUser1.setFirstName("John");
				stdUser1.setLastName("Doe");
				stdUser1.setEmail("user1@localhost");
				stdUser1.setEnabled(Boolean.TRUE);
				stdUser1.setDeleted(Boolean.FALSE);
				stdUser1.setActive(Boolean.TRUE);
				stdUser1.setAccountNonLocked(Boolean.TRUE);
				stdUser1.setAccountNonExpired(Boolean.TRUE);
				stdUser1.setCredentialsNonExpired(Boolean.TRUE);
			save(stdUser1);
			
			User stdUser2 = getUser();
				stdUser2.setUsername("user2");
				stdUser2.setPassword("password");
				stdUser2.setNickName("User 2");
				stdUser2.setFirstName("John");
				stdUser2.setLastName("Smith");
				stdUser2.setEmail("user2@localhost");
				stdUser2.setEnabled(Boolean.TRUE);
				stdUser2.setDeleted(Boolean.FALSE);
				stdUser2.setActive(Boolean.TRUE);
				stdUser2.setAccountNonLocked(Boolean.TRUE);
				stdUser2.setAccountNonExpired(Boolean.TRUE);
				stdUser2.setCredentialsNonExpired(Boolean.TRUE);
			save(stdUser2);					
		}
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#isUsernameAvailable(String username)
	 */
	@Override
	public boolean isUsernameAvailable(String username) {
		if(getUserByUsername(username,Boolean.TRUE) != null) {
			return Boolean.FALSE;
		}
		return Boolean.TRUE;
		
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#isNickNameAvailable(java.lang.String)
	 */
	@Override
	public boolean isNickNameAvailable(String nickname) {
		if(getUserByNickname(nickname ,Boolean.TRUE) != null) {
			return Boolean.FALSE;
		}
		return Boolean.TRUE;
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUniqueNickName(java.lang.String)
	 */
	@Override
	public String getUniqueNickName(String nickname) {
		String testNickName = nickname;
		int i = 1;
		while(!isNickNameAvailable(testNickName)){
			testNickName = nickname + "_" + i;
			i++;
		}
		return testNickName;
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByEmail(java.lang.String)
	 */
	@Override
	public User getUserByEmail(String email) {
		return getUserByEmail(email, Boolean.FALSE);
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.services.UserManager#getUserByEmail(java.lang.String, boolean)
	 */
	@Override
	public User getUserByEmail(String email, boolean force) {
		return ((UserDao)_dao).getUserByEmail(email,force);		
	}	
	
}
